/**
  * @(#)Application.java
  *
  * Coordinate the application initialization and execution
  *
  * @author Course Scheduler Team
  * 
  * @license GNU General Public License version 3 (GPLv3)
  *
  * This file is part of Course Scheduler, an open source, cross platform
  * course scheduling tool, configurable for most universities.
  *
  * Copyright (C) 2010-2012 Course Scheduler Team
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  * 
  */
package com.pollicitus.scheduler.core;

import java.io.FileNotFoundException;
import java.io.IOException;

import org.slf4j.Logger;

import com.pollicitus.scheduler.logging.LogManager;
import com.pollicitus.scheduler.profiles.ProfileManager;
import com.pollicitus.scheduler.util.DefaultResourceExtractor;


/**
 * Coordinate the application initialization and execution.
 * Application global state variables and settings are stored here.
 * 
 * @author Course Scheduler Team
 *
 */
public class Application {

	//application property names
	public static final String APPLICATION_LOG = "scheduler#logging.namespace";
	
	//application global variables
	public static Settings settings;
	public static Logger log;
	public static LogManager logManager;
	public static ProfileManager profManager;
	
	/**
	 * Initialize the application by loading the necessary 
	 * components, loading the application settings, initializing
	 * all relevant modules, etc.
	 * 
	 * @param args command line arguments to the application
	 * @throws IOException 
	 * @throws FileNotFoundException 
	 * @throws ClassNotFoundException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public static void initialize(String[] args) throws FileNotFoundException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException{
		//prepare application parameters and configuration settings
		Parameters parms = Parameters.getInstance(args);
		
		//catch missing base config file - indicative of corrupted or initial installation
		try{
			settings = Settings.getInstance(parms);
		}catch (FileNotFoundException e){			
			System.err.println("Base config files missing. See following exception for more details");
			e.printStackTrace(System.err);
			
			//materialize the files locally from the archive
			DefaultResourceExtractor.materializeLocalFiles();
			
			//try to get the settings again - do not catch exception. if materialize of config failed, then we have bigger issues 
			settings = Settings.getInstance(parms);
		}
		
		//initialize the logging subsystem and the primary logger
		logManager = LogManager.getInstance(settings);
		log = logManager.getLogger(settings.getProperty(APPLICATION_LOG));
		log.info("Application logging initiated");
		
		//initialize the profile manager
		log.info("Initializing the profile manager");
		profManager = ProfileManager.getInstance(settings);
		
		//TODO initialize UI 
			
		
	}
	
	/**
	 * Execute the application based on the application configuration.
	 */
	public static void execute(){
		//TODO execute the application primary component
		//which may be a UI or a server process depending
		//on the configuration being used at runtime
	}
	
	/**
	 * Finalize all open application components and prepare for proper
	 * application shutdown.
	 *
	 * @param args the command line arguments, only included to differentiate
	 * the method from the Object.finalize method which we are not attempting
	 * to override. Instead we overload for the necessary functionality.
	 * @throws IOException if there is a problem writing configFile files during finalization
	 * @throws FileNotFoundException if configFile files are missing during finalization
	 */
	public static void finalize(String[] args) throws FileNotFoundException, IOException{
		log.info("Preparing to shutdown application components");
		try{
			//TODO finalize the UI for proper shutdown

			log.info("Finalizing the profile manager");
			profManager.finalize(settings);
		}catch(Exception e){
			log.error("Exception caught during application finalization", e);
			log.info("Proceeding to finalize the log manager and settings");
		}finally{
			//properly close the log files
			log.info("Application logging completed. Final shutdown stages logging to console");
			logManager.finalize(settings);
			
			//last step is to save (if necessary) and close the open settings files
			settings.finalize(args);
		}
	}
}
